package com.cnbm.wcsbasic.protocol.netty.s7.retry;

import com.cnbm.wcsbasic.protocol.netty.s7.s7connector.exception.S7CheckResultException;
import com.cnbm.wcsbasic.protocol.netty.s7.s7connector.exception.S7IOException;
import com.cnbm.wcsbasic.protocol.netty.s7.s7connector.exception.S7ParseDataException;
import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * @author caixiang
 * @description 重试模板和重试策略
 */
public class S7RetryTemplate extends RetryTemplate {

    private volatile static S7RetryTemplate instance = null;
    /**
     * 重试间隔时间ms,默认1000ms
     * */
    private static long fixedPeriodTime = 500L;
    /**
     * 最大重试次数,默认为3
     */
    private static int maxRetryTimes = 3;
    /**
     * 表示哪些异常需要重试,key表示异常的字节码,value为true表示需要重试
     */
    private static Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<>();
    private S7RetryTemplate() {
        // 代表S7IOException 这个异常是需要重试的(true), 如果你想设置这个异常不去重试，那么可以把它设置为false。
        exceptionMap.put(S7IOException.class,true);
        exceptionMap.put(S7CheckResultException.class,true);
        exceptionMap.put(S7ParseDataException.class,true);
        //Exception
        //exceptionMap.put(Exception.class,true);

    }
    public static int getMaxRetryTimes() {
        return maxRetryTimes;
    }

    public static S7RetryTemplate getInstance() {
        if (instance == null) {
            synchronized (S7RetryTemplate.class) {
                if (instance == null) {
                    FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
                    // 定义重试间隔-间隔 fixedPeriodTime ms再重试,总共重试3次
                    backOffPolicy.setBackOffPeriod(fixedPeriodTime);
                    instance = new S7RetryTemplate();
                    // 定义重试次数- maxRetryTimes
                    SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(maxRetryTimes, exceptionMap);
                    instance.setRetryPolicy(retryPolicy);

                    instance.setBackOffPolicy(backOffPolicy);
                }
            }
        }
        return instance;
    }
}
